import 'package:dio/dio.dart';
import 'package:flutter_ai/utils/https/x_https_store.dart';
import 'package:flutter_ai/utils/x_logger.dart';

///
/// 关于网络请求工具类; 基于 dio 封装，提供了一些常用的网络请求方法，如 get、post
///
class XHttps {
  static XHttps? _instance;
  late final Dio _dio;

  // 私有构造函数
  XHttps._internal() {
    /// 初始化 dio
    _dio = Dio(BaseOptions(
      baseUrl: "https://api.deepseek.com/",
      connectTimeout: const Duration(seconds: 5),
      receiveTimeout: const Duration(seconds: 10),
      headers: {
        'Content-Type': 'application/json',
      },
    ));

    /// 添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 在请求被发送之前做一些处理
        XLogger.d('⏳请求url: ${options.uri}');
        XLogger.d('🏃🏻‍♀️请求头: ${options.headers}');
        XLogger.d('😁请求参数: ${options.data}');
        // 在请求被发送之前做一些处理
        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 在接收到响应数据之前做一些处理
        XLogger.d('✅请求数据源响应 response.data: ${response.data}');
        return handler.next(response);
      },
      onError: (DioException e, handler) {
        XLogger.e('❌请求数据源错误 e.response?.data: ${e.response?.data}');
        // 当请求失败时做一些处理
        XDioException error = XDioException.fromDioError(e);
        return handler.next(error);
      },
    ));
  }

  // 单例模式
  static XHttps getInstance() {
    _instance ??= XHttps._internal();
    return _instance!;
  }

  ///
  /// 设置请求头
  ///
  void setHeaders(Map<String, dynamic> headers) {
    _dio.options.headers.addAll(headers);
  }

  ///
  /// get 请求
  ///
  Future<Response<dynamic>> get(String path, {Map<String, dynamic>? params}) {
    return _request(XMethod.get, path, params: params);
  }

  ///
  /// post 请求
  ///
  Future<Response<dynamic>> post(String path, {Map<String, dynamic>? params}) {
    return _request(XMethod.post, path, params: params);
  }

  ///
  /// 私有请求方法
  ///
  Future<Response<dynamic>> _request(XMethod method, String path, {Map<String, dynamic>? params}) {
    return _dio.request(
      path,
      queryParameters: method == XMethod.get ? params : null,
      data: method == XMethod.get ? null : params,
      options: Options(method: method.value),
    );
  }
}
